<script setup lang="ts">
import { ref, onMounted, defineExpose } from 'vue'
import 'ol/ol.css'
import Map from 'ol/Map'
import View from 'ol/View'
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
import { XYZ, Vector as VectorSource, Cluster } from 'ol/source'
import Feature from 'ol/Feature'
import Point from 'ol/geom/Point'
import { Style, Icon, Text, Fill, Stroke, Circle } from 'ol/style'
import Overlay from 'ol/Overlay'
import { fromLonLat } from 'ol/proj'
import { gcj02ToWgs84 } from '@/utils/wgs84'
import GeoJSON from 'ol/format/GeoJSON'
// 导入API
import { getChannelList, type ChannelInfo, queryChildrenOrgList, getOrgMapStatistics } from '@/api/h3yun'
// 导入图标
import CAMERA_ICON from '@/assets/images/screen/ball.png'
import ORG_ICON from '@/assets/images/screen/org.png'
// 导入云南省边界数据
import YUNNAN_BOUNDARY_DATA from '@/assets/json/530000.json'
// 导入弹框组件
import MonitorPopup from '@/components/MonitorPopup.vue'
// 导入医院弹窗组件
import HospitalPopup from '@/components/HospitalPopup.vue'
// 导入视频预览组件
import VideoPreviewDialog from '@/components/VideoPreviewDialog.vue'

const mapRef = ref<HTMLDivElement>()
const map = ref<Map>()
// 当前选中的监控点信息
const selectedMonitorInfo = ref<MonitorInfo | null>(null)
// 当前选中的医院信息
const selectedHospitalInfo = ref<HospitalInfo | null>(null)
// 视频预览弹窗控制
const showVideoPreview = ref(false)
// 当前视频设备信息
const currentVideoDevice = ref<any>(null)
// 存储所有医院数据，用于关联
const hospitalData = ref<HospitalInfo[]>([])

// 天地图 token
const TIANDITU_TOKEN = 'fb6fa6a68c4a31cb6199d7561b5ba07c'

// 监控点详细信息接口，包含解析后的经纬度
interface MonitorInfo extends ChannelInfo {
  coordinates?: [number, number] // 经度和纬度
  status: 'online' | 'offline' | 'error'
  addressObj?: any // 保存解析后的地址对象
}

// 医院信息接口，包括关联的监控点
interface HospitalInfo {
  name: string
  ObjectId: string
  Address?: string
  Location?: string
  areaCode?: string
  areaName?: string
  children?: MonitorInfo[] // 关联的监控点列表
  count?: number // 监控点数量
  coordinates?: [number, number] // 经纬度
  [key: string]: any
}

// 地图统计数据
const mapStatistics = ref<Record<string, number>>({})

// 加载地图统计数据
const loadMapStatistics = async (areaCode: string = '') => {
  try {
    const response = await getOrgMapStatistics(areaCode)
    if (response.code === '0' && response.data) {
      mapStatistics.value = response.data
    } else {
      console.error('获取地图统计数据失败:', response.msg)
    }
  } catch (error) {
    console.error('加载地图统计数据失败:', error)
  }
}

// 创建点位数据
const createMonitorPoints = (channelList: ChannelInfo[]) => {
  const features: Feature[] = []
  console.log('处理监控点数据:', channelList)

  channelList.forEach(channel => {
    try {
      // 解析Address字段中的经纬度信息
      if (!channel.Address) return // 跳过Address为空的记录

      const addressObj = JSON.parse(channel.Address)
      if (!addressObj.Point || !addressObj.Point.lat || !addressObj.Point.lng) return

      const lat = addressObj.Point.lat
      const lng = addressObj.Point.lng
      
      // 转换状态
      let status: 'online' | 'offline' | 'error' = 'offline'
      if (channel.ChannelStatus === 1) {
        status = 'online'
      } else if (channel.ChannelStatus === 0) {
        status = 'offline'
      } else {
        status = 'error'
      }

      // 创建监控点对象
      const monitorInfo: MonitorInfo = {
        ...channel,
        coordinates: [lng, lat],
        status,
        addressObj // 保存解析后的地址对象，方便后续使用
      }

      // 关联监控点到医院
      if (channel.OrgId) {
        const hospital = hospitalData.value.find(h => h.ObjectId === channel.OrgId)
        if (hospital) {
          if (!hospital.children) {
            hospital.children = []
          }
          hospital.children.push(monitorInfo)
          
          // 更新医院的监控点计数
          hospital.count = (hospital.count || 0) + 1
        }
      }

      // 这里不再创建监控点Feature，因为现在只在医院弹窗中显示监控点
    } catch (error) {
      console.error('解析监控点数据失败:', error, channel)
    }
  })

  return features
}

// 创建带文字的样式
const createStyleWithText = (feature: Feature) => {
  return new Style({
    image: new Icon({
      anchor: [0.5, 0.5],
      anchorXUnits: 'fraction',
      anchorYUnits: 'fraction',
      src: CAMERA_ICON,
      scale: 1,
      opacity: 0.9
    }),
    text: new Text({
      text: feature.get('name'),
      font: 'bold 13px Microsoft YaHei',
      offsetY: -20,
      textAlign: 'center',
      textBaseline: 'bottom',
      fill: new Fill({
        color: '#ffffff'
      }),
      backgroundFill: new Fill({
        color: 'rgba(0, 0, 0, 0.75)'
      }),
      padding: [6, 10],
      stroke: new Stroke({
        color: 'rgba(0, 0, 0, 0.3)',
        width: 3
      })
    })
  })
}

// 创建聚合样式
const createClusterStyle = (feature: Feature) => {
  const size = feature.get('features').length
  
  // 单个点位使用摄像头图标
  if (size === 1) {
    return new Style({
      image: new Icon({
        anchor: [0.5, 0.5],
        anchorXUnits: 'fraction',
        anchorYUnits: 'fraction',
        src: CAMERA_ICON,
        scale: 1,
        opacity: 0.9
      })
    })
  }

  // 聚合点使用圆形+数字
  return new Style({
    image: new Circle({
      radius: 16, // 缩小圆圈
      fill: new Fill({
        color: 'rgba(103, 202, 246, 0.8)'
      }),
      stroke: new Stroke({
        color: '#fff',
        width: 2
      })
    }),
    text: new Text({
      text: size.toString(),
      fill: new Fill({
        color: '#fff'
      }),
      font: 'bold 12px Microsoft YaHei', // 缩小字体
      offsetY: 1
    })
  })
}

// 处理弹窗关闭
const handlePopupClose = () => {
  const popupElement = document.querySelector('.monitor-popup') as HTMLElement
  if (popupElement) {
    popupElement.style.display = 'none'
  }
  selectedMonitorInfo.value = null
  selectedHospitalInfo.value = null
}

// 处理医院弹窗中监控点选择
const handleMonitorSelect = (monitor: MonitorInfo) => {
  // 关闭医院弹窗
  const popupElement = document.querySelector('.monitor-popup') as HTMLElement
  if (popupElement) {
    popupElement.style.display = 'none'
  }
  selectedHospitalInfo.value = null
  
  // 显示监控点弹窗
  selectedMonitorInfo.value = monitor
  
  // 从原始监控点信息中获取准确的坐标
  if (monitor.coordinates) {
    // 将经纬度转换为Web墨卡托投影坐标
    
    // 设置弹窗位置
    const popup = map.value!.getOverlays().getArray().find(overlay => 
      overlay.getElement()?.className === 'monitor-popup'
    ) as Overlay
    
    if (popup) {
      // popup.setPosition(exactCoordinates);
      popupElement.style.display = 'block'
      
      // 中心点移动到坐标位置
      // map.value!.getView().animate({
      //   center: exactCoordinates,
      //   duration: 500,
      // }, () => {
      //   // 动画完成后显示弹窗
      //   popupElement.style.display = 'block'
      // })
    }
  }
}

// 处理视频预览请求
const handlePreview = () => {
  if (!selectedMonitorInfo.value) return
  
  // 设置视频设备信息
  currentVideoDevice.value = {
    name: selectedMonitorInfo.value.ChannelName || selectedMonitorInfo.value.Name || '未命名监控点',
    deviceSerial: selectedMonitorInfo.value.DeviceSerial,
    channelNo: selectedMonitorInfo.value.ChannelNo,
    status: selectedMonitorInfo.value.status
  }
  
  // 显示视频预览弹窗
  showVideoPreview.value = true
}

// 处理视频错误
const handleVideoError = (error: any) => {
  console.error('视频播放错误:', error)
}

/**
 * 定位到指定经纬度的方法
 * @param coordinates 经纬度坐标数组 [longitude, latitude]
 * @param zoom 可选的缩放级别，不传则保持当前缩放级别
 * @param duration 动画持续时间，默认500ms
 */
const locateToCoordinates = (coordinates: [number, number], zoom?: number, duration: number = 500) => {
  if (!map.value) return false;
  
  // 将经纬度转换为Web墨卡托投影坐标
  const transformedCoordinates = fromLonLat(gcj02ToWgs84(coordinates[0], coordinates[1]));
  
  // 准备动画配置
  const animateOptions: any = {
    center: transformedCoordinates,
    duration: duration
  };
  
  // 如果提供了缩放级别，添加到动画配置中
  if (zoom !== undefined) {
    animateOptions.zoom = zoom;
  }
  
  // 执行动画
  map.value.getView().animate(animateOptions);
  
  return true;
}

// 初始化地图
const initMap = async () => {
  if (!mapRef.value) return

  // 加载地图统计数据
  await loadMapStatistics()

  // 天地图影像图层
  const yxLayer = new TileLayer({
    source: new XYZ({
      url: `https://t{0-7}.tianditu.gov.cn/DataServer?T=img_c&tk=${TIANDITU_TOKEN}&x={x}&y={y}&l={z}`,
      projection: 'EPSG:4326'
    })
  })

  // 天地图影像标注图层
  const yxRoadLayer = new TileLayer({
    source: new XYZ({
      url: `https://t{0-7}.tianditu.gov.cn/DataServer?T=cia_c&tk=${TIANDITU_TOKEN}&x={x}&y={y}&l={z}`,
      projection: 'EPSG:4326'
    })
  })

  // 天地图矢量图层
  const slLayer = new TileLayer({
    source: new XYZ({
      url: `https://t{0-7}.tianditu.gov.cn/DataServer?T=vec_c&tk=${TIANDITU_TOKEN}&x={x}&y={y}&l={z}`,
      projection: 'EPSG:4326'
    })
  })

  // 天地图矢量标注图层
  const slRoadLayer = new TileLayer({
    source: new XYZ({
      url: `https://t{0-7}.tianditu.gov.cn/DataServer?T=cva_c&tk=${TIANDITU_TOKEN}&x={x}&y={y}&l={z}`,
      projection: 'EPSG:4326'
    })
  })

  // 昆明市坐标
  const kunmingLonLat = [102.693132, 25.040495]
  const kunming = fromLonLat(gcj02ToWgs84(kunmingLonLat[0], kunmingLonLat[1])) // 将经纬度坐标转换为Web墨卡托投影坐标

  map.value = new Map({
    target: mapRef.value,
    layers: [slLayer, slRoadLayer],
    view: new View({
      // projection: 'EPSG:3857', // 修改为Web墨卡托投影
      center: kunming,
      zoom: 15, // 调小默认缩放级别以显示更大范围
      minZoom: 5,
      maxZoom: 18
    })
  })

  // 添加云南省边界线
  // await loadYunnanBoundary()

  // 修改加载顺序：先加载医院数据
  await loadHospitalPoints()
  
  // 再加载监控点数据并与医院关联
  await loadMonitorPoints()

  // 添加鼠标样式
  map.value.on('pointermove', (event) => {
    const hit = map.value!.forEachFeatureAtPixel(event.pixel, (feature) => feature)
    map.value!.getTargetElement().style.cursor = hit ? 'pointer' : ''
  })

  // 创建弹窗 Overlay
  const popupElement = document.createElement('div')
  popupElement.className = 'monitor-popup'
  
  const popup = new Overlay({
    element: popupElement,
    positioning: 'bottom-center',
    offset: [0, -12], // 调整为 -12px，让弹窗更靠上一点
    autoPan: true
  })

  map.value.addOverlay(popup)

  // 点击事件处理
  map.value.on('click', (event) => {
    const feature = map.value!.forEachFeatureAtPixel(event.pixel, (feature) => feature)
    
    if (feature) {
      // 检查是否是聚合点
      if (feature.get('features')) {
        const features = feature.get('features')
        let coordinates = (feature.getGeometry() as Point).getCoordinates()

        // 如果是单个点位，显示详情
        if (features.length === 1) {
          const info = features[0].get('info')
          coordinates = fromLonLat(gcj02ToWgs84(info.Lng, info.Lat));
          
          // 判断是否为医院点位
          if (info && 'ObjectId' in info) {
            // 从hospitalData中获取完整的医院信息（包含关联的监控点）
            const hospital = hospitalData.value.find(h => h.ObjectId === info.ObjectId)
            
            if (hospital) {
              selectedHospitalInfo.value = hospital
              selectedMonitorInfo.value = null
              
              // 直接将点位移动到视图中心
              map.value!.getView().animate({
                center: coordinates,
                duration: 500,
              }, () => {
                // 动画完成后显示弹窗
                // 设置弹窗位置
                popup.setPosition(coordinates)
                popupElement.style.display = 'block'
              })
            } else {
              popupElement.style.display = 'none'
              selectedHospitalInfo.value = null
              selectedMonitorInfo.value = null
            }
          } else {
            popupElement.style.display = 'none'
            selectedHospitalInfo.value = null
            selectedMonitorInfo.value = null
          }
        } else {
          // 如果是聚合点，隐藏弹窗并放大地图
          popupElement.style.display = 'none'
          selectedHospitalInfo.value = null
          selectedMonitorInfo.value = null
          
          // 先定位中心点，再放大
          map.value!.getView().animate({
            center: coordinates,
            duration: 500
          }, () => {
            map.value!.getView().animate({
              zoom: map.value!.getView().getZoom()! + 2,
              duration: 500
            })
          })
        }
      } else {
        popupElement.style.display = 'none'
        selectedHospitalInfo.value = null
        selectedMonitorInfo.value = null
      }
    } else {
      popupElement.style.display = 'none'
      selectedHospitalInfo.value = null
      selectedMonitorInfo.value = null
    }
  })

  // 创建悬停提示元素
  const tooltipElement = document.createElement('div')
  tooltipElement.className = 'monitor-tooltip'
  
  const tooltip = new Overlay({
    element: tooltipElement,
    positioning: 'bottom-center',
    offset: [0, -9], // 增加偏移量，让提示显示在图标上方
    stopEvent: false
  })
  
  map.value.addOverlay(tooltip)

  // 鼠标移动事件处理 - 用于显示悬停提示
  map.value.on('pointermove', (event) => {
    // 更新鼠标样式
    const hit = map.value!.forEachFeatureAtPixel(event.pixel, (feature) => feature)
    map.value!.getTargetElement().style.cursor = hit ? 'pointer' : ''
    
    // 处理悬停提示
    if (hit) {
      // 检查是否是聚合点
      if (hit.get('features')) {
        const features = hit.get('features')
        
        // 如果只有一个点位，显示名称
        if (features.length === 1) {
          const feature = features[0]
          // 获取点位信息
          const info = feature.get('info')
          if (!info) {
            tooltipElement.style.display = 'none'
            return
          }
          
          const coordinates = (hit.getGeometry() as Point).getCoordinates()
          
          // 使用准确的坐标来定位悬停提示
          let exactCoordinates = coordinates;
          
          // 处理医院点位的坐标
          if ('coordinates' in info && info.coordinates) {
            // 将经纬度转换为Web墨卡托投影坐标
            exactCoordinates = fromLonLat(gcj02ToWgs84(info.coordinates[0], info.coordinates[1]));
          }
          
          // 显示名称，优先显示医院名称
          let name = '未命名点位'
          if ('name' in info) {
            name = info.name || '未命名医院'
          }
          
          // 添加监控点数量提示
          if ('count' in info && info.count) {
            name += ` (${info.count}个监控点)`
          }
          
          tooltipElement.textContent = name
          tooltipElement.style.display = 'block'
          tooltip.setPosition(exactCoordinates)
        } else {
          tooltipElement.style.display = 'none'
        }
      } else {
        tooltipElement.style.display = 'none'
      }
    } else {
      tooltipElement.style.display = 'none'
    }
  })

  // 鼠标离开地图时隐藏提示
  map.value.getTargetElement().addEventListener('mouseleave', () => {
    tooltipElement.style.display = 'none'
  })
}

// 加载云南省边界数据并添加边界线
const loadYunnanBoundary = async () => {
  try {
    console.log('加载云南省边界数据:', YUNNAN_BOUNDARY_DATA);
    
    // 创建边界线数据源
    const boundarySource = new VectorSource({
      features: new GeoJSON().readFeatures(YUNNAN_BOUNDARY_DATA, {
        dataProjection: 'EPSG:4326',  // GeoJSON数据通常使用EPSG:4326(WGS84)坐标系
        featureProjection: 'EPSG:3857' // 地图使用Web墨卡托投影
      })
    });
    
    // 创建边界线图层
    const boundaryLayer = new VectorLayer({
      source: boundarySource,
      style: new Style({
        stroke: new Stroke({
          color: '#DAA520', // 深黄色 (GoldenRod)
          width: 3,         // 线宽为3像素
        }),
        fill: new Fill({
          color: 'rgba(218, 165, 32, 0.05)' // 极淡的填充色，匹配边界线颜色
        })
      }),
      zIndex: 5 // 边界线在点位下方，在底图上方
    });
    
    // 添加边界线图层到地图
    map.value!.addLayer(boundaryLayer);
  } catch (error) {
    console.error('加载云南省边界线失败:', error);
  }
};

// 加载监控点数据并与医院关联
const loadMonitorPoints = async () => {
  try {
    // 调用API获取监控点列表
    const response = await getChannelList()
    
    if (response.code === '0' && response.data) {
      // 创建点位数据并关联到医院
      createMonitorPoints(response.data)
    } else {
      console.error('获取监控点列表失败:', response.msg)
    }
  } catch (error) {
    console.error('加载监控点数据失败:', error)
  }
}

// 加载下级单位(医院)数据
const loadHospitalPoints = async () => {
  try {
    // 调用API获取下级单位列表
    const response = await queryChildrenOrgList()
    
    if (response.code === '0' && response.data) {
      console.log('接收到的下级单位数据:', response.data)
      
      // 创建医院点位特征
      const features: Feature[] = []
      
      // 清空并重置医院数据
      hospitalData.value = []
      
      response.data.forEach(org => {
        // 解析Address字段中的经纬度信息
        org.name = org.Name
        org.Address = org.Location
        if (!org.Address) return // 跳过Address为空的记录
        
        try {
          const addressObj = JSON.parse(org.Address)
          if (!addressObj.Point || !addressObj.Point.lat || !addressObj.Point.lng) return

          const lat = addressObj.Point.lat
          const lng = addressObj.Point.lng

          // 获取该区域的统计数据
          const areaCode = org.areaCode || ''
          const count = mapStatistics.value[areaCode] || 0

          // 创建医院数据对象
          const hospital: HospitalInfo = {
            ...org,
            coordinates: [lng, lat],
            count: 0, // 初始化监控点计数为0
            children: [] // 初始化子节点为空数组
          }
          
          // 添加到医院数据列表
          hospitalData.value.push(hospital)

          // 转换到Web墨卡托投影坐标系
          const coordinates = fromLonLat(gcj02ToWgs84(lng, lat))
          
          const feature = new Feature({
            geometry: new Point(coordinates),
            name: org.name,
            info: hospital
          })
          
          // 设置样式 - 显示图标（不显示数量，因为后续会关联）
          const style = new Style({
            image: new Icon({
              anchor: [0.5, 0.5],
              anchorXUnits: 'fraction',
              anchorYUnits: 'fraction',
              src: ORG_ICON,
              scale: 1,
              opacity: 0.9
            })
          })
          
          feature.setStyle(style)
          features.push(feature)
        } catch (error) {
          console.error('解析医院数据失败:', error, org)
        }
      })
      
      console.log('生成的医院点位特征数量:', features.length)
      
      // 点位数据源
      const orgSource = new VectorSource({
        features: features
      })
      
      // 聚合数据源
      const orgClusterSource = new Cluster({
        distance: 40,
        minDistance: 20,
        source: orgSource
      })
      
      // 创建医院点位聚合样式
      const createHospitalClusterStyle = (feature: Feature) => {
        const size = feature.get('features').length
        
        // 单个点位使用医院图标
        if (size === 1) {
          const info = feature.get('features')[0].get('info')
          const count = info.count || 0
          
          return new Style({
            image: new Icon({
              anchor: [0.5, 0.5],
              anchorXUnits: 'fraction',
              anchorYUnits: 'fraction',
              src: ORG_ICON,
              scale: 1,
              opacity: 0.9
            }),
            text: count > 0 ? new Text({
              text: count.toString(),
              font: 'bold 12px Microsoft YaHei',
              offsetY: -20,
              textAlign: 'center',
              textBaseline: 'bottom',
              fill: new Fill({
                color: '#ffffff'
              }),
              backgroundFill: new Fill({
                color: 'rgba(0, 0, 0, 0.75)'
              }),
              padding: [4, 8],
              stroke: new Stroke({
                color: 'rgba(0, 0, 0, 0.3)',
                width: 2
              })
            }) : undefined
          })
        }
        
        // 聚合点使用圆形+数字
        return new Style({
          image: new Circle({
            radius: 16,
            fill: new Fill({
              color: 'rgba(246, 167, 103, 0.8)' // 橙色系，与监控点区分
            }),
            stroke: new Stroke({
              color: '#fff',
              width: 2
            })
          }),
          text: new Text({
            text: size.toString(),
            fill: new Fill({
              color: '#fff'
            }),
            font: 'bold 12px Microsoft YaHei',
            offsetY: 1
          })
        })
      }
      
      // 医院点位图层
      const orgLayer = new VectorLayer({
        source: orgClusterSource,
        style: createHospitalClusterStyle,
        zIndex: 10 // 调整为最高层级
      })
      
      // 添加医院点位图层到地图
      map.value!.addLayer(orgLayer)
    } else {
      console.error('获取下级单位列表失败:', response.msg)
    }
  } catch (error) {
    console.error('加载下级单位数据失败:', error)
  }
}

// 更新医院点位样式，在监控点关联后调用
const updateHospitalStyles = () => {
  // 如果地图尚未初始化，直接返回
  if (!map.value) return
  
  // 遍历地图的所有图层
  map.value.getLayers().forEach(layer => {
    // 判断是否是矢量图层
    if (layer instanceof VectorLayer) {
      const source = layer.getSource()
      
      // 判断是否是聚合数据源
      if (source instanceof Cluster) {
        // 刷新图层，触发样式重新计算
        source.refresh()
      }
    }
  })
}

onMounted(() => {
  initMap()
})

// 向外部暴露方法
defineExpose({
  locateToCoordinates
})
</script>

<template>
  <div ref="mapRef" class="map-container">
    <!-- 弹框组件 -->
    <Teleport to=".monitor-popup" v-if="selectedMonitorInfo">
      <MonitorPopup 
        :info="selectedMonitorInfo" 
        @close="handlePopupClose"
        @preview="handlePreview"
      />
    </Teleport>
    
    <!-- 医院弹窗组件 -->
    <Teleport to=".monitor-popup" v-if="selectedHospitalInfo && !selectedMonitorInfo">
      <HospitalPopup 
        :info="selectedHospitalInfo" 
        @close="handlePopupClose"
        @monitorSelect="handleMonitorSelect"
      />
    </Teleport>
    
    <!-- 视频预览弹窗组件 -->
    <VideoPreviewDialog 
      v-if="showVideoPreview"
      :visible="showVideoPreview"
      :title="`${currentVideoDevice?.name || '未命名监控点'} - 实时视频预览`"
      :camera-info="currentVideoDevice"
      @close="showVideoPreview = false"
      @error="handleVideoError"
    />
  </div>
</template>

<style scoped>
.map-container {
  width: 100%;
  height: 100%;
  background: #f5f5f5;
}

:deep(.monitor-popup) {
  position: relative;
  background: white;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
  border-radius: 4px;
  width: 300px; /* 将宽度从400px减小到300px */
  z-index: 1000;
  transform: translateY(-12px); /* 配合 offset 调整位置 */
}

:deep(.monitor-tooltip) {
  position: relative;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 4px 8px;
  border-radius: 2px;
  font-size: 12px;
  white-space: nowrap;
  pointer-events: none;
  z-index: 999;
  transform: translateY(-18px); /* 上移一些，避免遮挡图标 */
}

:deep(.monitor-tooltip::after) {
  content: '';
  position: absolute;
  bottom: -6px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 6px solid rgba(0, 0, 0, 0.7);
}

:deep(.monitor-popup::after) {
  content: '';
  position: absolute;
  bottom: -8px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-top: 8px solid white;
  filter: drop-shadow(0 2px 2px rgba(0,0,0,0.1));
}
</style> 